﻿using System;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using Configuration = NHibernate.Cfg.Configuration;

namespace ConfigByAppConfig
{
    /// <summary>
    /// configuration 정보의 deserialize시간을 단축하여
    /// 시스템 초기 시작 시간을 단축하려...
    /// </summary>
    class ConfigurationBuilder
    {
        private const string SERIALIZED_CFG = "configuration.bin";

        public Configuration Build()
        {
            Configuration cfg = LoadConfigurationFromFile();
            if (cfg == null)
            {
                cfg = new Configuration().Configure();
                SaveConfigurationToFile(cfg);
            }

            return cfg;
        }

        private Configuration LoadConfigurationFromFile()
        {
            if (!IsConfigurationFileValid())
                return null;

            try
            {
                using (var file = File.Open(SERIALIZED_CFG, FileMode.Open))
                {
                    var bf = new BinaryFormatter();
                    return bf.Deserialize(file) as Configuration;
                }
            }
            catch (Exception)
            {
                return null;
            }

        }

        private bool IsConfigurationFileValid()
        {
            if (!File.Exists(SERIALIZED_CFG))
                return false;

            var configInfo = new FileInfo(SERIALIZED_CFG);

            var asm = Assembly.GetExecutingAssembly();
            if (asm.Location == null)
                return false;

            var asmInfo = new FileInfo(asm.Location);
            if(asmInfo.LastWriteTime > configInfo.LastWriteTime)
                return false;

            var appDomain = AppDomain.CurrentDomain;
            var appConfigPath = appDomain.SetupInformation.ConfigurationFile;
            var appConfigInfo = new FileInfo(appConfigPath);
            if (appConfigInfo.LastWriteTime > configInfo.LastWriteTime)
                return false;

            return true;
        }

        private void SaveConfigurationToFile(Configuration cfg)
        {
            using (var file = File.Open(SERIALIZED_CFG, FileMode.Create))
            {
                var bf = new BinaryFormatter();
                bf.Serialize(file, cfg);
            }
        }
    }
}
